package lxs.swift.fn;

import lxs.swift.operation.Try;
import org.jetbrains.annotations.NotNull;

import java.util.function.BiFunction;

public interface BiFunc<T, U, R, E extends Throwable> extends Fn<BiFunction<T, U, R>> {
    R apply(T t, U u) throws E;

    @Override
    default BiFunction<T, U, R> std() {
        return (t, u) -> Try.valueOf(() -> this.apply(t, u)).ret();
    }

    static <T, U, E extends Throwable> BiFunc<T, U, T, E> left() {
        return (t, u) -> t;
    }

    static <T, U, E extends Throwable> BiFunc<T, U, U, E> right() {
        return (t, u) -> u;
    }

    static <T, U, R, E extends Throwable> BiFunc<T, U, R, E> none() {
        return (t, u) -> null;
    }

    static <T, U, R, E extends Throwable> BiFunc<T, U, R, E> panic(@NotNull E error) {
        return (t, u) -> {
            throw error;
        };
    }
}
